<?php
/***
* AjaxPint: Ajax based PHP Command Interpreter 
* by R.ay  paltalk @ gmail.com
* 
* 18 Feb 2007
*
* Idea: Developer can check his php code online. 
* Pros: Simple and wonderful way ...
*
* Used of eval may be risky
* Solution: A string filter should be added to filter out malacious commands
*
* Dependency: It uses prototype.js for ajaxing.
*
* 

*/

$safeFunctions = array(
                    'array',        'echo',            'print',
                    'printf',        'SimpleXML',    'preg_match'
                     );
                 
 if(!empty($_POST['input'])) {
    $sCode = stripslashes($_POST['input']);
        
     /**
      * 1. trim input; remove the comment blocks (not implemented)
      * 2. add newly defined function in safe list
      * 3. find out all functions, including definition
      * 4. check if all these are in safe list or not. if not, show error
      */
      
     // The safe function list
     $safeFunctions = array(
                        'array',    'echo',        'print',
                        'printf',    'SimpleXML','preg_match'
                     );
     
     // the pattern to match function definition
     $functionDefinitionPattern = '/function[\s]+([\w]+)[\s]*\(/';
     
    // $sCode = '<?php ' .
    //         'echo (\"hello\"); ' .
    //         'hello(32, 2); // a sample() comment' .
    //         'function myFunc ($varname);' .
    //         '/* another ' .
    //         'comment() */' .
    //         'abrakadabra, function(now(what)) adfjs';
             
     
         
     $matches = null;
     preg_match_all($functionDefinitionPattern, $input, $matches);
     //print_r($matches[1]);
      
     foreach($matches[1] as $value) {
         $safeFunctions[] = $value;
     }
     
      
     // pattern to math all function calls, including function definitions
     $functionCallPattern = '/([\w]+)[\s]*\(/';
     if($num = preg_match_all($functionCallPattern, $input, $matches)) {
         //print_r($matches[1]);
     }
     
     $usedFunctions = $matches[1];
     $isSafe = true;
     $illegalFunctions = array();
     foreach($usedFunctions as $value) {
         if(!in_array($value, $safeFunctions)) {
             $isSafe = false;
             $illegalFunctions[] = $value;
         }
     }
     
     if(!$isSafe) {
         echo "<br /><font color=red>you've used these illegal functions: </font>";
         foreach($illegalFunctions as $value)
             echo $value . " ";
         return;
     }
            
            
            //echo str_replace("\$", "\\$", $sCode);
           // echo $sCode;
     eval("?>".$sCode."<?");
            
     return;
 }
 if(!empty($_POST['submit']))
      return;
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>SIMPLEST PHP CODE LAB</title>
<style type="text/css">
<!--
#output {
    background-color: #FFFFCC;
    border: thin dashed;
    height: inherit;
}
-->
</style>
</head>
<script src="http://24ways.org/examples/easy-ajax-with-prototype/prototype.js" language="javascript"></script>
<script language="javascript">
     function greet(){
        var code = input.getCode();
        if(code == "") {
            
            input.setCode("<? ?>");
            return false;
        }
        var url = '<?php echo $_SERVER[PHP_SELF];?>';
         var pars = 'input='+escape(code);
         var target = 'output';
         var myAjax = new Ajax.Updater(target, url, {method: 'post', parameters: pars});
    }

    function validate() {
        var code = input.getCode();
        return false;
        if(code == "") {
            alert("Please enter a valid php code");
            return false;
        }
        else
            return true;
    }
    
</script>
<link type="text/css" href="codepress/languages/php.css" rel="stylesheet" id="cp-lang-style" />
<script src="codepress/codepress.js" type="text/javascript"></script>    
 <script type="text/javascript">
    CodePress.language = 'php';
    
</script>
</head>
<body>
<span left: 10px; font-size: 17px; color: navy;>Ajaxpint - Interactive PHP interpreter</span>
<form onsubmit="greet(); return false;">
  <textarea id="input" cols="80" rows ="5"  class="codepress php linenumbers-on"></textarea><br />
  <input type="submit" onclick="validate()" value="Submit"/>
  <input type="button" onclick="input.toggleEditor();"/ value="Toggle Editor">    
</form>
<div id="output">
</div>
</body>
</html>
